package com.zzl.admin.password;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class AesUtil {

    public AesUtil() {

    }

    public static String encrypt(String content, String secret) throws Exception {
        SecretKey secretKey = getKey(secret);
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
        cipher.init(1, key);
        byte[] result = cipher.doFinal(byteContent);
        return parseByte2HexStr(result);
    }

    public static String decrypt(String encryptResultHexStr, String secret) throws Exception {
        byte[] decryptFrom = parseHexStr2Byte(encryptResultHexStr);
        SecretKey secretKey = getKey(secret);
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(2, key);
        assert decryptFrom != null;
        byte[] result = cipher.doFinal(decryptFrom);
        return new String(result, StandardCharsets.UTF_8);
    }

    private static String parseByte2HexStr(byte[] buf) {
        StringBuilder sb = new StringBuilder();
        for (byte b : buf) {
            String hex = Integer.toHexString(b & 255);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }

            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    private static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        } else if (hexStr.length() % 2 != 0) {
            return null;
        } else {
            byte[] result = new byte[hexStr.length() / 2];

            for(int i = 0; i < hexStr.length() / 2; ++i) {
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
                result[i] = (byte)(high * 16 + low);
            }

            return result;
        }
    }

    private static SecretKey getKey(String secret) throws Exception {
        KeyGenerator generator = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(secret.getBytes());
        generator.init(128, secureRandom);
        return generator.generateKey();
    }

}
